package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.leanring.LearningLessonDTO;
import com.tianji.api.dto.leanring.LearningRecordDTO;
import com.tianji.api.dto.leanring.LearningRecordFormDTO;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.delaytask.LearningRecordDelayTaskHandler;
import com.tianji.learning.domain.po.LearningLesson;
import com.tianji.learning.domain.po.LearningRecord;
import com.tianji.learning.enums.LessonStatus;
import com.tianji.learning.enums.SectionType;
import com.tianji.learning.mapper.LearningRecordMapper;
import com.tianji.learning.service.ILearningLessonService;
import com.tianji.learning.service.ILearningRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 学习记录表 服务实现类
 * </p>
 *
 * @author Ys
 * @since 2023-08-07
 */
@Transactional
@Service
public class LearningRecordServiceImpl extends ServiceImpl<LearningRecordMapper, LearningRecord> implements ILearningRecordService {

    @Autowired
    private ILearningLessonService learningLessonService;

    //1. 根据userId和courseId从learning_lesson查询课表
    //2. 根据lesson_id从learning_record查询学习记录合集
    //3. 封装LearningLessDTO
    //4. 返回结果
    @Override
    public LearningLessonDTO queryLearningRecordByCourse(Long courseId) {
        //1. 根据userId和courseId从learning_lesson查询课表
        LearningLesson learningLesson = learningLessonService.lambdaQuery()
                .eq(LearningLesson::getCourseId, courseId)
                .eq(LearningLesson::getUserId, UserContext.getUser())
                .one();
        //2. 根据lesson_id从learning_record查询学习记录集合
        List<LearningRecord> learningRecordList = this.lambdaQuery()
                .eq(LearningRecord::getLessonId, learningLesson.getId())
                .eq(LearningRecord::getUserId,UserContext.getUser())
                .list();
        //3. 封装LearningLessonDTO
        LearningLessonDTO learningLessonDTO = new LearningLessonDTO();
        learningLessonDTO.setId(learningLesson.getId());// 课表id
        learningLessonDTO.setLatestSectionId(learningLesson.getLatestSectionId());// 最近学习的小结id
        List<LearningRecordDTO> learningRecordDTOList = BeanUtil.copyToList(learningRecordList, LearningRecordDTO.class);
        learningLessonDTO.setRecords(learningRecordDTOList); // 学习过的小结的记录
        //4. 返回记录
        return learningLessonDTO;
    }


    @Autowired
    private CourseClient courseClient;

    //1. 提交学习记录
    //2. 更新课表
    // 提交学习记录
    @Override
    public void addLearningRecord(LearningRecordFormDTO learningRecordFormDTO) {
      //1. 提交学习记录
        Boolean finished=false;
        //判断记录考试还是视频
        if(learningRecordFormDTO.getSectionType()==SectionType.EXAM.getValue()){
            //1-1 考试记录
            finished=handlerExamRecord(learningRecordFormDTO);
        }else {
            //1-2 视频记录
            finished=handlerVideoRecord(learningRecordFormDTO);
        }
        //2.更新课表
        handlerLearningLessonChanges(learningRecordFormDTO,finished);
    }

    //抽取处理更新课表逻辑方法
    private void handlerLearningLessonChanges(LearningRecordFormDTO learningRecordFormDTO, Boolean finished) {
        //1. 查询课表
        LearningLesson learningLesson = learningLessonService.getById(learningRecordFormDTO.getLessonId());
        //2. 查询课程
        CourseFullInfoDTO courseFullInfoDTO = courseClient.getCourseInfoById(learningLesson.getCourseId(), false, false);
        //3. 更新学习状态: 未学习->学习中
        if(learningLesson.getStatus().getValue()==LessonStatus.NOT_BEGIN.getValue()){
            learningLesson.setStatus(LessonStatus.LEARNING);//学习中
        }
        //4. 更新最近学习小结和时间
        learningLesson.setLatestSectionId(learningRecordFormDTO.getSectionId());
        learningLesson.setLatestLearnTime(learningRecordFormDTO.getCommitTime());
        //5. 判断小结是否是第一次学完
        if(finished){
            // 如果是，课表学习小结+1
            learningLesson.setLearnedSections(learningLesson.getLearnedSections()+1);
            // 判断是否学完全部小结
            if(learningLesson.getLearnedSections()>=courseFullInfoDTO.getSectionNum()){
                //如果是更新课程状态为已学完
                learningLesson.setStatus(LessonStatus.FINISHED);
            }
        }
        //6. 更新数据库
        learningLessonService.updateById(learningLesson);
    }

    // 抽取处理考试记录逻辑方法
    private Boolean handlerExamRecord(LearningRecordFormDTO learningRecordFormDTO) {
        //1. dto->po
        LearningRecord learningRecord = BeanUtil.copyProperties(learningRecordFormDTO, LearningRecord.class);
        //2. 补充属性
        learningRecord.setUserId(UserContext.getUser());
        learningRecord.setFinished(true);
        learningRecord.setFinishTime(learningRecordFormDTO.getCommitTime());
        //3. 保存到数据库
        this.save(learningRecord);
        //4. 返回已学完
        return true;
    }

    @Autowired
    private LearningRecordDelayTaskHandler taskHandler;

    // 抽取处理视频记录逻辑方法
    private Boolean handlerVideoRecord(LearningRecordFormDTO learningRecordFormDTO) {
        //1. 查询学习记录是否存在
        // 线程缓存中查询，如果没有再从数据库查询，同步Redis
        boolean finished =false;
        LearningRecord learningRecord = taskHandler.readCache(learningRecordFormDTO.getLessonId(),
                learningRecordFormDTO.getSectionId());
        if(learningRecord == null) {
            learningRecord = this.lambdaQuery()
                    .eq(LearningRecord::getLessonId, learningRecordFormDTO.getLessonId())
                    .eq(LearningRecord::getSectionId, learningRecordFormDTO.getSectionId())
                    .one();
            if (learningRecord != null) {
                taskHandler.writeCache(learningRecord);
            }

            if (learningRecord == null) { //2. 如果不存在，就新增一条
                //2-1 dto->po
                learningRecord = BeanUtil.copyProperties(learningRecordFormDTO, learningRecord.getClass());
                //2-2 补充属性
                learningRecord.setUserId(UserContext.getUser());
                //2-3 保存到数据库
                this.save(learningRecord);
                //2-4 返回未学完
                return false;
            }
        }else {
            //3. 如果存在，就更新一条
            //3-1 判断是否是一次看完 (时长>50%,finished=false)
             finished = learningRecord.getFinished() == false && learningRecordFormDTO.getMoment() * 2 > learningRecordFormDTO.getDuration();
            if(finished){
                //3-2 第一次看完
                learningRecord.setFinished(true);// 已完成
                learningRecord.setFinishTime(learningRecordFormDTO.getCommitTime());// 完成时间
                learningRecord.setMoment(learningRecord.getMoment());//视频进度
                //更新数据库
                this.updateById(learningRecord);
                //清理redis缓存
                taskHandler.cleanCache(learningRecord.getLessonId(),learningRecord.getSectionId());
            }else {
                //3-3 不是第一次看完
                // 填充播放时长
                learningRecord.setMoment(learningRecordFormDTO.getMoment());
                //更新redis
                taskHandler.writeCache(learningRecord);
            }
            //3-3 返回标识
            return finished;

        }
        return finished;

    }



}
